/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package avl.sv.client;

import avl.sv.shared.Annotations.Annotation;
import avl.sv.shared.Annotations.Attributes;
import avl.sv.shared.Annotations.ROI;
import avl.sv.shared.SlideReference;
import avl.sv.shared.XML.AnnotationXML_Writer;
import avl.sv.shared.sources.SlideSource;
import avl.tiff.TiffTag;
import com.sun.media.jai.codec.JPEGEncodeParam;
import com.sun.media.jai.codec.TIFFEncodeParam;
import com.sun.media.jai.codec.TIFFField;
import com.sun.media.jai.codecimpl.TIFFImageEncoder;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import javax.media.jai.TiledImage;
import javax.swing.JFileChooser;

/**
 *
 * @author benbryan
 */
public class ExportDialogROIs extends javax.swing.JDialog {

    private final SlideSource slideSource;
    private Object[] exportObjs;
    
    /**
     * Creates new form NewJDialog
     */
    public ExportDialogROIs(java.awt.Frame parent, boolean modal, SlideSource slideSource) {
        super(parent, modal);
        this.slideSource = slideSource;
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ExportDialogROIs.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        
        initComponents();
        
        File f = jFileChooserOutputDir.getFileSystemView().getDefaultDirectory();
        jFileChooserOutputDir.setCurrentDirectory(f);
        jFileChooserOutputDir.setSelectedFile(f);
        jFileChooserOutputDir.setMultiSelectionEnabled(false);
        jFileChooserOutputDir.setAcceptAllFileFilterUsed(false);
        jFileChooserOutputDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        jTextFieldOutputDir.setText(f.getAbsolutePath());
       
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jFileChooserOutputDir = new javax.swing.JFileChooser();
        jTextFieldNumOfSelectedROIs = new javax.swing.JTextField();
        jButtonExport = new javax.swing.JButton();
        jButtonCancel = new javax.swing.JButton();
        jLabel3 = new javax.swing.JLabel();
        jTextFieldOutputDir = new javax.swing.JTextField();
        jLabel2 = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jSpinnerJpegQuality = new javax.swing.JSpinner();

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        setTitle("Export ROIs Dialog");
        setModalityType(java.awt.Dialog.ModalityType.APPLICATION_MODAL);

        jTextFieldNumOfSelectedROIs.setEnabled(false);

        jButtonExport.setText("Export");
        jButtonExport.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonExportActionPerformed(evt);
            }
        });

        jButtonCancel.setText("Cancel");
        jButtonCancel.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonCancelActionPerformed(evt);
            }
        });

        jLabel3.setText("Number of ROIs Selected");

        jTextFieldOutputDir.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                jTextFieldOutputDirMouseClicked(evt);
            }
        });

        jLabel2.setText("JPEG Quality");

        jLabel1.setText("Output Directory");

        jSpinnerJpegQuality.setModel(new javax.swing.SpinnerNumberModel(95, 10, 100, 1));

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(jButtonCancel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jButtonExport))
                    .addComponent(jTextFieldOutputDir)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(jLabel1)
                            .addGroup(layout.createSequentialGroup()
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                    .addComponent(jSpinnerJpegQuality)
                                    .addComponent(jTextFieldNumOfSelectedROIs, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 81, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel3))))
                        .addGap(0, 0, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTextFieldOutputDir, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jTextFieldNumOfSelectedROIs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2)
                    .addComponent(jSpinnerJpegQuality, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButtonExport)
                    .addComponent(jButtonCancel))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonExportActionPerformed
        for (Object obj : exportObjs) {
            if (obj instanceof ROI) {
                ROI roi = (ROI) obj;
                exportROI(roi);

            }
            if (obj instanceof Annotation) {
                ArrayList<ROI> rois = ((Annotation) obj).getRois();
                for (ROI roi : rois) {
                    exportROI(roi);
                }
            }
        }
        setVisible(false);
    }//GEN-LAST:event_jButtonExportActionPerformed

    private void jButtonCancelActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonCancelActionPerformed
        setVisible(false);
    }//GEN-LAST:event_jButtonCancelActionPerformed

    private void jTextFieldOutputDirMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jTextFieldOutputDirMouseClicked
        jFileChooserOutputDir.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        jFileChooserOutputDir.setDialogTitle("Choose output directory");
        jFileChooserOutputDir.setApproveButtonText("Select Folder");
        if (jFileChooserOutputDir.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            jTextFieldOutputDir.setText(jFileChooserOutputDir.getSelectedFile().getAbsolutePath());
        }
    }//GEN-LAST:event_jTextFieldOutputDirMouseClicked

    public void exportROI(ROI roi) {
        try {
            Rectangle rec = roi.getPolygon().getBounds();
            if (rec.x < 0){
                rec.x = 0;
            }
            if (rec.y < 0){
                rec.y = 0;
            }
            if (rec.width >= slideSource.getImageDimX()){
                rec.width = slideSource.getImageDimX();
            }
            if (rec.height >= slideSource.getImageDimY()){
                rec.height = slideSource.getImageDimY();
            }
            String imageType = "tiff";
            for (int i = 0; i < 9999; i++) {
                String num = i == 0 ? "" : "_" + String.valueOf(i);
                File out = new File(jFileChooserOutputDir.getSelectedFile() + File.separator + roi.text + num + "." + imageType);
                if (out.exists()) {
                    continue;
                }
                if (out.getParentFile().canWrite()) {
                    BufferedImage temp = slideSource.getSubImage(rec);
                    TiledImage img = new TiledImage(0, 0, temp.getWidth(), temp.getHeight(), 0, 0, temp.getSampleModel(), temp.getColorModel());
                    img.createGraphics().drawImage(temp, null, this);
                    float jpegQuality = Math.round(((float)jSpinnerJpegQuality.getValue())/100);
                    FileOutputStream fos = new FileOutputStream(out);
                    int tileSize = 256;

                    TIFFEncodeParam tiffParam = new TIFFEncodeParam();
                    tiffParam.setCompression(TIFFEncodeParam.COMPRESSION_JPEG_TTN2);
                    tiffParam.setWriteTiled(true);
                    tiffParam.setTileSize(tileSize, tileSize);
                    tiffParam.setLittleEndian(true);

                    JPEGEncodeParam jpegParam = tiffParam.getJPEGEncodeParam();
                    jpegParam.setQuality(jpegQuality);

                    Annotation anno = new Annotation();
                    anno.add((ROI) roi.clone());
                    Attributes boundingBoxAttribute = new Attributes();
                    boundingBoxAttribute.id = 0;
                    boundingBoxAttribute.name = "Annotation_BoundingBox";
                    boundingBoxAttribute.value = 
                            "X="        + String.valueOf(rec.x)     + "|" +  
                            "Y="        + String.valueOf(rec.y)     + "|" + 
                            "Width="    + String.valueOf(rec.width) + "|" + 
                            "Height="   + String.valueOf(rec.height);   
                    if (anno.attributes == null){
                        anno.attributes = new ArrayList<>();
                    }
                    anno.attributes.add(boundingBoxAttribute);
                    
                    Attributes sourceImage = new Attributes();
                    sourceImage.id = 1;
                    sourceImage.name = "Source image";
                    SlideReference slideReference = slideSource.getSlideReference();
                    sourceImage.value = slideReference.slideSetName + "\"" + slideReference.slideName;
                    anno.attributes.add(sourceImage);
                    
                    TIFFField[] extraFields = new TIFFField[1];
                    extraFields[0] = new TIFFField(TiffTag.ImageDescription.getShort(), 2, 1, new String[]{AnnotationXML_Writer.getXMLString(anno)});
                    tiffParam.setExtraFields(extraFields);
                    
                    TIFFImageEncoder encoder = new TIFFImageEncoder(fos, tiffParam);
                    encoder.encode(img);
                    fos.close();
                    
                    return;
                }
            }

        } catch (IOException ex) {
            System.out.println("failed to get Subimage");
            System.out.println(ex);
        }
    }
       
    public void promptForExport(Object exportObjs[]) {
        this.exportObjs = exportObjs;
        int numOfROIs = 0;
        for (Object obj : exportObjs) {
            if (obj instanceof ROI) {
                numOfROIs++;
             }
            if (obj instanceof Annotation) {
                ArrayList<ROI> rois = ((Annotation) obj).getRois();
                numOfROIs+= rois.size();
            }
        }
        jTextFieldNumOfSelectedROIs.setText(String.valueOf(numOfROIs));
        setVisible(true);
    }
        
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonCancel;
    private javax.swing.JButton jButtonExport;
    private javax.swing.JFileChooser jFileChooserOutputDir;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JSpinner jSpinnerJpegQuality;
    private javax.swing.JTextField jTextFieldNumOfSelectedROIs;
    private javax.swing.JTextField jTextFieldOutputDir;
    // End of variables declaration//GEN-END:variables
}
